﻿using JunionRobotTaskManager.Models;
using SqlSugar;
using SqlSugar.IOC;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace JunionRobotTaskManager.Repository
{
    public class BaseRepository<T> : SimpleClient<T>, IBaseRepository<T> where T : class, new()
    {
    
       
        
        public BaseRepository(ISqlSugarClient context) : base(context)
        {


                base.Context = context;





            #region 创建数据库
#if DEBUG

            //创建数据库 运行一次然后注释掉就行了
            base.Context.DbMaintenance.CreateDatabase();
            //创建表
            base.Context.CodeFirst.InitTables(
              typeof(Robot),
              typeof(Job),
              typeof(TransferPort),
              typeof(Dock),
              typeof(Park)

              );
#endif
            #endregion
        }

        #region 事务

        /// <summary>
        /// 开始事务
        /// </summary>
        public void BeginTran()
        {
            Context.Ado.BeginTran();
        }

        /// <summary>
        /// 事务提交
        /// </summary>
        public void Commit()
        {
            Context.Ado.CommitTran();
        }

        /// <summary>
        /// 事务回滚
        /// </summary>
        public void Rollback()
        {
            Context.Ado.RollbackTran();
        }

        #endregion

        #region 添加

        /// <summary>
        /// 插入数据
        /// </summary>
        /// <param name="entity">实体类</param>
        /// <returns></returns>
        public bool Add(T entity)
        {
            return base.Insert(entity);
        }

        /// <summary>
        /// 插入数据异步方法
        /// </summary>
        /// <param name="entity">实体类</param>
        /// <returns></returns>
        public async Task<bool> AddAsync(T entity)
        {
            return await base.InsertAsync(entity);
        }

        /// <summary>
        /// 批量添加数据
        /// </summary>
        /// <param name="entities">实体类集合</param>
        /// <returns></returns>
        public bool AddList(IList<T> entities)
        {
            return base.InsertRange(entities.ToArray());
        }

        /// <summary>
        /// 批量添加数据 异步方法
        /// </summary>
        /// <param name="entities">实体类集合</param>
        /// <returns></returns>
        public async Task<bool> AddListAsync(IList<T> entities)
        {
            return await base.InsertRangeAsync(entities.ToArray());
        }

        #endregion

        #region 修改

        /// <summary>
        /// 修改数据
        /// </summary>
        /// <param name="entity">要修改的实体类</param>
        /// <returns></returns>
        public bool UpdateEntity(T entity)
        {
            return base.Update(entity);
        }

        /// <summary>
        /// 修改数据 异步方法
        /// </summary>
        /// <param name="entity">要修改的实体类</param>
        /// <returns></returns>
        public Task<bool> UpdateEntityAsync(T entity)
        {
            return base.UpdateAsync(entity);
        }


        /// <summary>
        /// 批量修改数据
        /// </summary>
        /// <param name="entity">实体类集合</param>
        /// <returns></returns>
        public bool UpdateList(IList<T> entities)
        {
            return base.UpdateRange(entities.ToArray());
        }

        /// <summary>
        /// 批量修改数据 异步方法
        /// </summary>
        /// <param name="entity">要修改的实体类</param>
        /// <returns></returns>
        public Task<bool> UpdateListAsync(IList<T> entities)
        {
            return base.UpdateRangeAsync(entities.ToArray());
        }

        #endregion

        #region 删除

        #region 根据Id删除

        /// <summary>
        /// 删除数据
        /// </summary>
        /// <param name="id">主键或者唯一的字段</param>
        /// <returns></returns>
        public new async Task<bool> DeleteByIdAsync(object id)
        {
            return await base.DeleteByIdAsync(id);
        }

        /// <summary>
        /// 删除数据
        /// </summary>
        /// <param name="id">主键或者唯一的字段</param>
        /// <returns></returns>
        public new bool DeleteById(object id)
        {
            return base.DeleteById(id);
        }

        /// <summary>
        /// 根据ids批量删除 异步方法
        /// </summary>
        /// <param name="ids">主键数组或者唯一性字段数组</param>
        /// <returns></returns>
        public new async Task<bool> DeleteByIdsAsync(object[] ids)
        {
            return await base.DeleteByIdsAsync(ids);
        }

        /// <summary>
        /// 根据ids批量删除 异步方法
        /// </summary>
        /// <param name="ids">主键数组或者唯一性字段数组</param>
        /// <returns></returns>
        public new bool DeleteByIds(object[] ids)
        {
            return base.DeleteByIds(ids);
        }

        /// <summary>
        /// 批量删除
        /// </summary>
        /// <param name="ids">主键数组或者唯一性字段数组</param>
        /// <returns></returns>
        public Task<bool> DeleteByIdsAsync(Expression<Func<T, bool>> func)
        {
            return base.DeleteByIdAsync(func);
        }
        /// <summary>
        /// 批量删除
        /// </summary>
        /// <param name="func">条件信息</param>
        /// <returns></returns>
        public bool DeleteByCondition(Expression<Func<T, bool>> func)
        {
            return base.Delete(func);
        }

        /// <summary>
        /// 批量删除
        /// </summary>
        /// <param name="func">条件信息</param>
        /// <returns></returns>
        public async Task<bool> DeleteByConditionAsync(Expression<Func<T, bool>> func)
        {
            return await base.DeleteAsync(func);
        }
        #endregion

        #region 根据实体删除

        /// <summary>
        /// 根据实体删除
        /// </summary>
        /// <param name="entity">实体</param>
        /// <returns></returns>
        public bool DeleteByEntity(T entity)
        {
            return base.Delete(entity);
        }


        /// <summary>
        /// 根据实体删除
        /// </summary>
        /// <param name="entity">实体</param>
        /// <returns></returns>
        public async Task<bool> DeleteByEntityAsync(T entity)
        {
            return await base.DeleteAsync(entity);
        }



        #endregion

        #endregion

        #region 查找

        #region 根据Id查找

        /// <summary>
        /// 功能描述:根据ID查询一条数据 异步方法
        /// </summary>
        /// <param name="id">Id主键</param>
        /// <returns></returns>
        public virtual async Task<T> FindByIdAsync(object id)
        {
            return await base.GetByIdAsync(id);
        }

        /// <summary>
        /// 功能描述:根据ID查询一条数据 同步方法
        /// </summary>
        /// <param name="id">Id主键</param>
        /// <returns></returns>
        public virtual T FindById(object id)
        {
            return  base.GetById(id);
        }

        #endregion

        #region 条件查询和全部查询

        /// <summary>
        /// 根据条件查询单个数据
        /// </summary>
        /// <param name="func">筛选条件</param>
        /// <returns></returns>
        public virtual async Task<T> FindAsync(Expression<Func<T, bool>> func)
        {
               return  await base.GetFirstAsync(func);
        }

        /// <summary>
        /// 根据条件查询单个
        /// </summary>
        /// <param name="func">筛选条件</param>
        /// <returns></returns>
        public virtual T Find(Expression<Func<T, bool>> func)
        {
            return  base.GetFirst(func);
        }



        /// <summary>
        /// 查询全部的数据
        /// </summary>
        /// <returns></returns>
        public virtual async Task<List<T>> QueryAsync()
        {
            return await base.GetListAsync();
        }


        /// <summary>
        /// 查询全部的数据
        /// </summary>
        /// <returns></returns>
        public virtual  List<T> Query()
        {
            return  base.GetList();
        }

        /// <summary>
        /// 自定义条件查询 异步方法
        /// </summary>
        /// <param name="func">Where条件</param>
        /// <returns></returns>
        public async Task<List<T>> QueryAsync(Expression<Func<T, bool>> func)
        {
            return await base.GetListAsync(func);
        }

        /// <summary>
        /// 自定义条件查询 同步方法
        /// </summary>
        /// <param name="func">Where条件</param>
        /// <returns></returns>
        public  List<T> Query(Expression<Func<T, bool>> func)
        {
            return base.GetList(func);
        }

       

        #endregion

        #region 存在性查找
        /// <summary>
        /// 检查是否存在 异步方法
        /// </summary>
        /// <param name="func">筛选条件表达式</param>
        /// <returns></returns>
        public async  Task<bool> CheckExistAsync(Expression<Func<T, bool>> func)
        {
            return await base.AsQueryable().AnyAsync(func);
        }

        /// <summary>
        /// 检查是否存在 异步方法
        /// </summary>
        /// <param name="func">筛选条件表达式</param>
        /// <returns></returns>
        public bool CheckExist(Expression<Func<T, bool>> func)
        {
            return  base.AsQueryable().Any(func);
        }

        #endregion

        #region 分页查询


        /// <summary>
        /// 分页查询
        /// </summary>
        /// <param name="page">页码</param>
        /// <param name="size">分页大小</param>
        /// <param name="total">总数</param>
        /// <returns></returns>
        public virtual async Task<List<T>> QueryAsync(int page, int size, RefAsync<int> total)
        {
            return await base.Context.Queryable<T>().ToPageListAsync(page, size, total);
        }

        /// <summary>
        /// 分页查询 异步方法
        /// </summary>
        /// <param name="page">页码</param>
        /// <param name="size">分页大小</param>
        /// <param name="total">总数</param>
        /// <returns></returns>
        public virtual  List<T> Query(int page, int size, ref int total)
        {
            return  base.Context.Queryable<T>().ToPageList(page, size,ref  total);
        }

       

        /// <summary>
        /// 自定义条件分页查询
        /// </summary>
        /// <param name="func">筛选条件</param>
        /// <param name="page">页码</param>
        /// <param name="size">分页大小</param>
        /// <param name="total">总数</param>
        /// <returns></returns>
        /// <returns></returns>
        public virtual async Task<List<T>> QueryAsync(Expression<Func<T, bool>> func, int page, int size, RefAsync<int> total)
        {
            return await base.Context.Queryable<T>()
                                    .Where(func)
                                    .ToPageListAsync(page, size, total);
        }

        /// <summary>
        /// 自定义条件分页查询
        /// </summary>
        /// <param name="func">筛选条件</param>
        /// <param name="page">页码</param>
        /// <param name="size">分页大小</param>
        /// <param name="total">总数</param>
        /// <returns></returns>
        /// <returns></returns>
        public virtual List<T> Query(Expression<Func<T, bool>> func, int page, int size, ref int total)
        {
            return  base.Context.Queryable<T>()
                                    .Where(func)
                                    .ToPageList(page, size, ref total);
        }

        /// <summary>
        /// 多条件分页查询
        /// </summary>
        /// <param name="conditionalModels">多个条件</param>
        /// <param name="page">页码</param>
        /// <param name="size">分页大小</param>
        /// <param name="total">总数</param>
        /// <returns></returns>
        public virtual async Task<List<T>> QueryAsync(List<IConditionalModel> conditionalModels, int page, int size, RefAsync<int> total)
        {
            return await base.Context.Queryable<T>()
                                    .Where(conditionalModels)
                                    .ToPageListAsync(page, size, total);
        }

        /// <summary>
        /// 多条件分页查询
        /// </summary>
        /// <param name="conditionalModels">多个条件</param>
        /// <param name="page">页码</param>
        /// <param name="size">分页大小</param>
        /// <param name="total">总数</param>
        /// <returns></returns>
        public virtual List<T> Query(List<IConditionalModel> conditionalModels, int page, int size, ref int total)
        {

            return  base.Context.Queryable<T>()
                                    .Where(conditionalModels)
                                    .ToPageList(page, size, ref total);
        }
        #endregion

        #region 原始Sql查询

        /// <summary>
        /// 批量原始Sql查询 异步方法
        /// </summary>
        /// <param name="sql">sql查询语句</param>
        /// <returns></returns>
        public virtual async Task<List<T>> SqlQueryToListAsync(string sql)
        {
            return await base.AsSugarClient().SqlQueryable<T>(sql).ToListAsync();
        }

        /// <summary>
        /// 批量原始Sql查询 同步方法
        /// </summary>
        /// <param name="sql">sql查询语句</param>
        /// <returns></returns>
        public virtual List<T> SqlQueryToList(string sql)
        {
            return  base.AsSugarClient().SqlQueryable<T>(sql).ToList();
        }

        /// <summary>
        /// 原始Sql查询,异步查询
        /// </summary>
        /// <param name="sql">sql查询</param>
        /// <returns></returns>
        public virtual async  Task<T> SqlQueryAsync(string sql)
        {
            return await base.AsSugarClient().SqlQueryable<T>(sql).FirstAsync();
        }

        /// <summary>
        /// 原始Sql查询,同步查询
        /// </summary>
        /// <param name="sql">sql查询</param>
        /// <returns></returns>
        public virtual  T SqlQuery(string sql)
        {
            return  base.AsSugarClient().SqlQueryable<T>(sql).First();
        }

        
        /// <summary>
        /// 原始Sql 执行 增删改方法
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
        public virtual async  Task<int> ExecuteCommandAsync(string sql)
        {
            return await base.Context.Ado.ExecuteCommandAsync(sql);
        }

        /// <summary>
        /// 原始Sql 执行 增删改方法
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
        public virtual int ExecuteCommand(string sql)
        {
            return base.Context.Ado.ExecuteCommand(sql);
        }
        /// <summary>
        /// 原始Sql 执行查询
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
        public List<TEntity> SqlQueryToList<TEntity>(string sql)
        {
            return base.Context.Ado.SqlQuery<TEntity>(sql);
        }
        /// <summary>
        /// 原始Sql 执行查询
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
        public TEntity SqlQuery<TEntity>(string sql)
        {
            return base.Context.Ado.SqlQuery<TEntity>(sql).First();
        }





        #endregion

        #endregion

    }
}
